package com.boss.redis.util.distributedlock.aspect;

import com.boss.redis.util.RedissonUtil;
import com.boss.redis.util.distributedlock.annotation.DistributedLock;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Aspect
@Component
@Slf4j
public class DistributedLockHandler {
    @Autowired
    private RedissonUtil redissonUtil;

    @Pointcut("@annotation(com.boss.redis.util.distributedlock.annotation.DistributedLock)")
    public void distributedLock() {
    }

    @SneakyThrows
    @Around("@annotation(distributedLock)")
    public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {
        log.debug("获取Redis分布式锁开始...");
        String lockName = distributedLock.value();
        if (StringUtils.isEmpty(lockName)) {
            throw new RuntimeException("获取redis分布式锁时，注解缺少锁名称");
        }
        /**获取超时时间，默认十秒*/
        int expireSeconds = distributedLock.expireSeconds();
        log.debug("Redis分布式锁的过期时间为:{}", expireSeconds);
        if (redissonUtil.lock(lockName, expireSeconds)) {
            try {
                log.debug("获取Redis分布式锁[成功]，加锁完成，开始执行业务逻辑...");
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                log.error("获取分布式锁后执行业务逻辑失败", throwable);
                throw new RuntimeException("获取分布式锁后执行业务逻辑失败", throwable);
            } finally {
                redissonUtil.unlock(lockName);
            }
//            log.debug("释放Redis分布式锁[成功]，解锁完成，结束业务逻辑...");
        } else {
            log.error("获取Redis分布式锁[失败]");
            throw new RuntimeException("系统繁忙,获取redis分布式锁失败");
        }
//        log.debug("[结束]执行RedisLock环绕通知");
//        return joinPoint.proceed();
    }
}
